package tom.vertx.core.util;

import io.vertx.core.DeploymentOptions;
import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.util.Optional;
import java.util.function.Consumer;

/**
 * 运行vertx类
 * @author ZHUFEIFEI
 */
@Slf4j
public class MainRunner {
    private static final String CORE_EXAMPLES_DIR = "vertx-util";
    private static final String CORE_EXAMPLES_JAVA_DIR = CORE_EXAMPLES_DIR + "/src/main/java/";

    static {
    }

    public static void run(Class clazz) {
        run(CORE_EXAMPLES_JAVA_DIR, clazz);
    }

    /**
     * run vertx
     * @param workDir e.g vertx-util/src/main/java/
     * @param clazz
     */
    public static void run(String workDir, Class clazz) {
        run(workDir, clazz, null, null);
    }

    public static void run(String workDir, Class clazz, VertxOptions options, DeploymentOptions deploymentOptions) {
        run(workDir + clazz.getPackage().getName().replace(".", "/"), clazz.getName(), options, deploymentOptions);
    }

    public static void run(String workDir, String verticleId, VertxOptions options, DeploymentOptions deploymentOptions) {
        try {
            //设置工作目录, 如果同一个项目内的子模块,直接去掉根目录
            File current = new File(".").getCanonicalFile();
            if (workDir.startsWith(current.getName()) && !workDir.equals(current.getName())) {
                workDir = workDir.substring(current.getName().length() + 1);
            }
        } catch (IOException e) {
        }

        //设置工作目录系统变量,FileResolver使用
        System.setProperty("vertx.cwd", workDir);
        log.info("run: {} with cwd: {}", verticleId, workDir);
        Consumer<Vertx> runner = vertx -> {
            log.info("deploy verticle: {}", verticleId);
            vertx.deployVerticle(
                    verticleId
                    ,Optional.ofNullable(deploymentOptions).orElse(new DeploymentOptions())
                    );
        };
        options = Optional.ofNullable(options).orElse(new VertxOptions());
        if (options.getEventBusOptions().isClustered()) {
            Vertx.clusteredVertx(options, res -> {
                log.info("create cluster vertx: {}", res.succeeded());
                if (res.succeeded()) {
                    Vertx vertx = res.result();
                    runner.accept(vertx);
                } else {
                    res.cause().printStackTrace();
                }
            });
        } else {
            Vertx vertx = Vertx.vertx(options);
            log.info("create vertx.");
            runner.accept(vertx);
        }
    }

}
